package org.mybatis.generator.api.plus;

import java.util.Iterator;
import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

/**
 * @author wangfupeng
 */

public class MybatisPluginAdditionalWhere extends PluginAdapter {
    public boolean validate(List<String> warnings) {
        return true;
    }

    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        FullyQualifiedJavaType stringWrapper = FullyQualifiedJavaType.getStringInstance();

        Field additionalWhere = new Field();
        additionalWhere.setName("additionalWhere");
        additionalWhere.setVisibility(JavaVisibility.PRIVATE);
        additionalWhere.setType(stringWrapper);
        topLevelClass.addField(additionalWhere);

        Method setAdditionalWhere = new Method();
        setAdditionalWhere.setFinal(true);
        setAdditionalWhere.setVisibility(JavaVisibility.PUBLIC);
        setAdditionalWhere.setName("setAdditionalWhere");
        setAdditionalWhere.addParameter(new Parameter(stringWrapper, "additionalWhere"));
        setAdditionalWhere.addBodyLine("this.additionalWhere = additionalWhere;");
        topLevelClass.addMethod(setAdditionalWhere);

        Method getAdditionalWhere = new Method();
        getAdditionalWhere.setFinal(true);
        getAdditionalWhere.setVisibility(JavaVisibility.PUBLIC);
        getAdditionalWhere.setReturnType(stringWrapper);
        getAdditionalWhere.setName("getAdditionalWhere");
        getAdditionalWhere.addBodyLine("return additionalWhere;");
        topLevelClass.addMethod(getAdditionalWhere);

        return true;
    }

    public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        boolean isUpdate = false;
        Attribute attr;
        for (Iterator localIterator = element.getAttributes().iterator(); localIterator.hasNext(); ) {
            attr = (Attribute) localIterator.next();
            if (attr.getName().equalsIgnoreCase("id")) {
                String value = attr.getValue();
                if (!value.startsWith("Update")) {
                    break;
                }
                isUpdate = true;
                break;
            }
        }
        XmlElement whereElement = null;
        for (Element ele : element.getElements()) {
            if ((ele instanceof XmlElement)) {
                XmlElement e = (XmlElement) ele;
                if ("where".equals(e.getName())) {
                    whereElement = e;
                    break;
                }
            }
        }
        if (whereElement != null) {
            String clause = "additionalWhere";
            if (isUpdate) {
                clause = "example.additionalWhere";
            }
            XmlElement ifAdditionalWhereNotNullElement = new XmlElement("if");
            ifAdditionalWhereNotNullElement.addAttribute(new Attribute("test", clause + " != null"));
            ifAdditionalWhereNotNullElement.addElement(new TextElement("and ${" + clause + "}"));
            whereElement.addElement(ifAdditionalWhereNotNullElement);
        }
        return true;
    }
}
